
import request from 'request';
import { removeWxToken } from '../controllers/wx_token';
import { sendLogToEmail } from '../controllers/logger';
import { exesql } from '../database/db';

/**
 *  获取用户的openid
 * @param {微信公众号appid} appId 
 * @param {微信公众号secret} appSecret 
 * @param {微信授权码} code 
 */
export function getOpenId(appId, appSecret, code) {
    const url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' + appId + '&secret=' + appSecret + '&code=' + code + '&grant_type=authorization_code';
    console.log(`getOpenId url:${url}`);
    return new Promise(function (resolve, reject) {
        request(url, function (error, res, data) {
            resolve({ err: error, result: data });
            if (error) {
                sendWxError(error, url,data);
            }
        })
    });

}


/**
 * 
 * @param {微信token} wxToken 
 * @param {用户id列表} openids 
 */
export function getUserListByOpenids(wxToken, openids) {
    const url = 'https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=' + wxToken;
    const post = {
        user_list: openids
    };
    const options = {
        headers: { "Connection": "close" },
        url: url,
        method: 'POST',
        json: true,
        body: post
    };
    return new Promise(function (resolve, reject) {
        request(options, function (error, res, data) {
            if (!error && res.statusCode == 200) {
                if (data.errcode === 40001) {
                    resolve({ err: null, list: [] });
                    return;
                }
                let userList = [];
                console.log(`getUserListByOpenids:`,data);
                if (data.user_info_list) {
                    for (let index = 0; index < data.user_info_list.length; index++) {
                        const user = data.user_info_list[index];
                        if (user.nickname) {
                            userList.push(user);
                        }
                    }
                }

                resolve({ err: null, list: userList });
            } else {
                resolve({ err: error, list: [] });
                sendWxError(error, url,options);
            }
        })
    });
}

/**
 * 发送微信消息给用户
 * @param {*} wxToken 
 * @param {*} touser 
 * @param {*} media_id 
 */
export function sendToWXUser(wxToken, toUser, media_id) {
    const url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + wxToken;
    const post = {
        touser: toUser,
        msgtype: 'voice',
        voice: {
            media_id: media_id
        }
    };
    const options = {
        headers: { "Connection": "close" },
        url: url,
        method: 'POST',
        json: true,
        body: post
    };
    return new Promise(function (resolve, reject) {
        request(options, function (error, res, data) {
            if (error) {
                sendWxError(error, url,data);
                return resolve({ err: error });
            }
            if (data.errcode === 0) {
                return resolve({ err: null });
            }else {
                console.log(JSON.stringify(data));
                if (data.errcode === 40001) {
                    removeWxToken(wxToken);
                }
                sendWxError(error, url,data);
                return resolve({ err: error,result:data});
            }
        })
    });
}


/**
 * 发送通知升级模板消息
 * @param {微信公众号配置信息} item 
 */
export function upgradeNotification(item) {
    const url = "https://" + item.host + "/upgrade/:" + item.new_version + "/:" + item.uuid;
    const post = {
        "touser": item.open_id,
        "template_id": item.template_id,
        "url": url,
        "data": {
            "first": {
                "value": "尊敬的用户，您好！" + item.name + "有新的软件版本啦",
                "color": "#173177"
            },
            "keyword1": {
                "value": item.name,
                "color": "#173177"
            },
            "keyword2": {
                "value": item.cur_version || "1.0.0",
                "color": "#173177"
            },
            "keyword3": {
                "value": item.new_version,
                "color": "#173177"
            },
            "remark": {
                "value": "请立即升级！",
                "color": "#173177"
            }
        }
    };
    const options = {
        headers: { "Connection": "close" },
        url: item.url,
        method: 'POST',
        json: true,
        body: post
    };

    return new Promise(function (resolve, reject) {
        request(options, function (error, res, data) {
            resolve({ err: error, result: data });
            if (error) {
                sendWxError(error, url,options);
            }
        })
    });
}


/**
 * 关注公众号之后,提醒用户绑定设备
 * @param {微信Token} wxToken 
 * @param {接收信息微信用户id} openid 
 * @param {微信公众号配置信息} item 
 */
export function sendBindDeviceNotification(wxToken, openid, item) {
    const url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + wxToken;
    const post = {
        "touser": openid,
        "msgtype": "news",
        "news": {
            "articles": [
                {
                    "title": "感谢您的关注，请先联网绑定设备",
                    "description": "请点击图片开始联网绑定您的设备",
                    "url": "https://" + item.host + "/?func=wxbind&wechat_id=" + item.wechat_id,
                    "picurl": item.bind_img_name
                },
            ]
        },
    };

    const options = {
        headers: { "Connection": "close" },
        url: url,
        method: 'POST',
        json: true,
        body: post
    };

    return new Promise(function (resolve, reject) {
        request(options, function (error, res, data) {
            resolve({ err: error, result: data });
            if (error) {
                sendWxError(error, url,options);
            }
        })
    });
}


/**
 * 获取分享设备的二维码
 * @param {微信token} wxToken 
 * @param {设备序列号} deviceSn 
 */
export function getShareDeviceQRCode(wxToken, deviceSn) {
    const url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' + wxToken;
    const post = {
        "expire_seconds": 2592000,
        "action_name": "QR_STR_SCENE",
        "action_info": {
            "scene": {
                "scene_str": deviceSn,
            }
        }
    };
    const options = {
        headers: { "Connection": "close" },
        url: url,
        method: 'POST',
        json: true,
        body: post
    };
    return new Promise(function (resolve, reject) {
        request(options, function (error, res, data) {
            resolve({ err: error, result: data });
            if (!error && res.statusCode !== 200) {
                if (data.errcode === 40001) {
                    removeWxToken(wxToken);
                    return;
                }
            }
            if (error) {
                sendWxError(error, url,options);
            }
        })
    })
}


/**
 * 发送消息给指定的用户
 * @param {微信token} wxToken 
 * @param {接收消息用户id} openId 
 * @param {消息} message 
 */
export function sendMessageToOpenid(wxToken, openId, message) {
    const url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=' + wxToken;
    const data_json = {
        "touser": openId,
        "msgtype": "text",
        "text": {
            "content": message
        }
    };
    const opt = {
        headers: { "Connection": "close" },
        url: url,
        method: 'POST',
        json: true,
        body: data_json
    };
    return new Promise(function (resolve, reject) {
        request(opt, function (error, res, data) {
            if (error) {
                sendWxError(error, url,opt);
            }
            resolve({ err: error, result: data })
        })
    })

}


/**
 * 发送有用户绑定设备信息
 * @param {微信token} wxToken 
 * @param {设备序列号} device_sn 
 * @param {当前微信用户id} curOpenid 
 */
export async function sendNewMemberMessage(wxToken, device_sn, curOpenid) {
    try {
        const data = await getUserListByOpenids(wxToken, [{
            "openid": curOpenid,
            "lang": "zh_CN"
        }]);
        if (data.err) {
            console.log('获取用户信息失败:', data.err);
            sendLogToEmail(data.err);
            return;
        }
        if (data.list.length === 0) {
            return;
        }
        const nickname = data.list[0].nickname;
        console.log(`nickname:${nickname}`);
        const { err, result } = await exesql('SELECT open_id FROM device_openid WHERE device_sn = ?', device_sn);
        if (err) {
            sendLogToEmail(err);
            return;
        }
        if (result.length > 0) {
            for (let index = 0; index < result.length; index++) {
                const item = result[index];
                const wxResult = await sendMessageToOpenid(wxToken,
                    item.open_id, item.open_id == curOpenid ? `通知:你已绑定设备。` : `通知:有新用户 ${nickname} 加入。`);
                if (wxResult.err) {
                    console.error(`发送通知给绑定用户:`, wxResult.err);
                }
            }
        }

    } catch (error) {
        sendLogToEmail(error);
    }
}

/**
 * 
 * @param {微信token} wxToken 
 * @param {设备序列号} device_sn 
 * @param {当前用户id} curOpenid 
 * @param {被动删除} isPassiveRemove 
 */
export async function sendUnbindMessage(wxToken,device_sn,curOpenid,isPassiveRemove){
    try {
        const data = await getUserListByOpenids(wxToken, [{
            "openid": curOpenid,
            "lang": "zh_CN"
        }]);
        if (data.err) {
            console.log('获取用户信息失败:', data.err);
            sendLogToEmail(data.err);
            return;
        }
        console.log(`data.list.length:${data.list.length}`);
        if (data.list.length === 0) {
            return;
        }
        const nickname = data.list[0].nickname;
        console.log(`nickname:${nickname}`);
        const { err, result } = await exesql('SELECT open_id FROM device_openid WHERE device_sn = ?', [device_sn]);
        if (err) {
            sendLogToEmail(err);
            return;
        }
        console.log(`result`, result);
        if (result.length > 0) {
            for (let index = 0; index < result.length; index++) {
                const item = result[index];
                const wxResult = await sendMessageToOpenid(wxToken,item.open_id,  isPassiveRemove ? `通知:${nickname} 已被移出家庭圈。`:`通知:${nickname} 已退出家庭圈。`);
                if (wxResult.err) {
                    console.error(`发送通知给绑定用户:`, wxResult.err);
                }
                console.log(wxResult.result);
            }
            await sendMessageToOpenid(wxToken,curOpenid,  isPassiveRemove ? `通知:你已被移出家庭圈。`: `通知:你已退出家庭圈`);
        }
    } catch (error) {
        sendLogToEmail(error);
    }
}


/**
 * 
 * @param {错误信息} error 
 * @param {微信请求URL} url 
 * @param {请求参数信息} options 
 */
function sendWxError(error, url,options){
    let errMeg = '';
    if (error instanceof Error) {
        errMeg = error.stack;
    }
    console.log(`sendWxError:${url},`,JSON.stringify(options));
    if (options && (options.errcode === 45047 || options.errcode === 45015)) {
        return;
    }

    sendLogToEmail(`${errMeg} \n -> url:${url} \n options:${JSON.stringify(options)}`);
}


